from pydantic import BaseModel, Field, HttpUrl
from typing import List, Mapping, Protocol, Optional
from playwright.async_api import Page
from asyncio import Event


class SimpleNewsItem(BaseModel):
    title: str
    published_time: str
    url: str
    raw_url: str
    content: str
    byline: Optional[str] = Field(default="")
    navigators: Optional[List[str]] = Field(default=[])


class NewsItem(BaseModel):
    title: str = Field(description="页面或文章标题")
    url: str = Field(description="页面URL")
    raw_url: str = Field(description="原始URL")
    content: str = Field(description="HTML string of processed article content;")
    text_content: str = Field(
        description="text content of the article, with all the HTML tags removed;"
    )
    excerpt: str = Field(
        description="article description, or short excerpt from the content;",
        default="",
    )
    byline: Optional[str] = Field(description="author metadata;")
    navigators: Optional[List[str]] = Field(default=[])
    length: int = Field(description="length of an article, in characters;", default=0)
    lang: str = Field(description="content language;", default="")
    published_time: str = Field(description="published time;", default="")


class Element(Protocol):
    def xpath(self, selector: str) -> "Element": ...
    def css(self, selector: str) -> "Element": ...
    def get(
        self,
    ) -> str: ...
    def getall(
        self,
    ) -> List[str]: ...


class Request(BaseModel):
    url: HttpUrl
    meta: Optional[Mapping] = Field(default=None)
    depth: int = Field(default=1)


class Response(BaseModel):
    request: Request
    url: HttpUrl
    content: str
    page: Optional[Page] = None
    model_config = {"arbitrary_types_allowed": True}


class SpiderConfig(BaseModel):
    allowed_domains: List[str]
    allowed_paths: List[str] = Field(default=[])
    blocked_paths: List[str] = Field(default=[])


class Selectors(BaseModel):
    time_selectors: List = Field(
        description="发布时间选择器",
        default=[
            "//*[@*='time' or @*='updatetime']",
            ".post_info",
            ".media-meta",
            ".date",
        ],
    )
    title_selectors: List = Field(description="标题选择器", default=["title"])
    author_selectors: List = Field(
        description="作者选择器", default=["//*[@*='author-name']", ".author"]
    )
    content_selectors: List = Field(
        description="正文选择器", default=["//*[@*='article']"]
    )
    nav_selectors: List = Field(description="导航信息选择器", default=[".breadcrumb a"])


class API(Protocol):
    event: Event

    def run(self): ...
    async def add_request(self):...